package com.imm.da.base.vb

import android.view.View
import androidx.annotation.LayoutRes
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import androidx.viewbinding.ViewBinding
import com.imm.da.base.BaseFragment
import java.lang.reflect.ParameterizedType
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

/**
 * <p>------------------------------------------------------
 * <p> Copyright (C) 2021 zhangmz, All rights reserved.
 * <p> If there is technical discussion, you can contact zhangmz90@foxmail.com
 * <p>------------------------------------------------------
 * <p> des
 * <p>
 *
 * @author Created by zhangmz
 * @date on 2021/12/5
 */
open class BaseVBFragment<VM : ViewModel>(@LayoutRes val resId: Int) : BaseFragment(resId) {

    /**
     * 可调用的 ViewModel
     */
    protected val viewModel: VM by lazy {
        val vmClass = (this.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<VM>
        ViewModelProvider(this)[vmClass]
    }

    inline fun <reified VB : ViewBinding> bindView() =
        BindingDelegate(VB::class.java)

    class BindingDelegate<VB : ViewBinding>(private val clazz: Class<VB>) :
        ReadOnlyProperty<Fragment, VB> {

        private var isInitialized = false
        private var _binding: VB? = null
        private val binding: VB get() = _binding!!

        override fun getValue(thisRef: Fragment, property: KProperty<*>): VB {
            if (!isInitialized) {
                thisRef.viewLifecycleOwner.lifecycle.addObserver(object : LifecycleObserver {
                    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
                    fun onDestroyView() {
                        _binding = null
                    }
                })
                _binding = clazz.getMethod("bind", View::class.java)
                    .invoke(null, thisRef.requireView()) as VB
                isInitialized = true
            }
            return binding
        }
    }

}